package net.sf.odinms.scripting.npc;

import java.sql.*;//hairi Mission
import net.sf.odinms.database.DatabaseConnection;//hairi Mission
import org.slf4j.Logger;//hairi Mission
import org.slf4j.LoggerFactory;//hairi Mission
import net.sf.odinms.net.PacketProcessor;//hairi Mission

import java.util.Arrays; //hairi 1VS1 PK房间
import net.sf.odinms.server.maps.MapleMapObject;
import net.sf.odinms.server.maps.MapleMapObjectType;


import java.awt.Point;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.Map.Entry;
import net.sf.odinms.scripting.AbstractPlayerInteraction;
import net.sf.odinms.scripting.event.EventManager;
import net.sf.odinms.server.quest.MapleQuest;
import net.sf.odinms.tools.MaplePacketCreator;
import net.sf.odinms.net.world.guild.MapleGuild;
import net.sf.odinms.server.*;
import net.sf.odinms.client.*;
import net.sf.odinms.database.DatabaseConnection;
import net.sf.odinms.net.channel.ChannelServer;
import net.sf.odinms.net.world.*;
import net.sf.odinms.server.life.*;
import net.sf.odinms.server.maps.*;
import net.sf.odinms.tools.Pair;

public class NPCConversationManager extends AbstractPlayerInteraction {

    private MapleClient c;
    private int npc;
    private String getText;
    private ChannelServer cserv;
    private MapleCharacter chr;
    private static Logger log = LoggerFactory.getLogger(PacketProcessor.class); //hairi Mission

    public NPCConversationManager(MapleClient c, int npc) {
        super(c);
        this.c = c;
        this.npc = npc;
    }

    public NPCConversationManager(MapleClient c, int npc, MapleCharacter chr) {
        super(c);
        this.c = c;
        this.npc = npc;
        this.chr = chr;
    }
    
    //强制关闭NPC对话 cm.dispose();
    public void dispose() {
        NPCScriptManager.getInstance().dispose(this);
    }

    //显示一个带“继续”按钮的对话窗口 cm.sendNext("[text]");
    public void sendNext(String text) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "00 01"));
    }

    //显示一个带“返回”按钮的对话窗口 cm.sendPrev("[text]");
    public void sendPrev(String text) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "01 00"));
    }

    //显示一个带“继续”和“返回”按钮的对话窗口 cm.sendNextPrev("[text]");
    public void sendNextPrev(String text) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "01 01"));
    }

    //显示一个带“好”按钮的对话窗口 cm.sendOk("[text]");
    public void sendOk(String text) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "00 00"));
    }
    
    //显示一个带“是”和“否”按钮的对话窗口，选“否”结束对话，否则做相反处理。 cm.sendYesNo("[text]");
    public void sendYesNo(String text) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 1, text, ""));
    }

    //显示一个带“接受”和“拒绝”按钮的对话窗口，选“拒绝”结束对话，否则做相反处理。 cm.sendAcceptDecline("[text]");
    public void sendAcceptDecline(String text) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0x0C, text, ""));
    }

    //显示一个无按钮的对话窗口 cm.sendAcceptSimple("[text]");
    public void sendSimple(String text) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 4, text, ""));
    }

    //显示一个选择性的对话窗口 cm.sendStyle("[Text]", [variable]); //需要声明一个变量
    public void sendStyle(String text, int styles[]) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalkStyle(npc, text, styles));
    }

    //显示一个要求玩家输入数字的弹出界面 text是显示文字，def是默认数字,min是最小数字,max是最大数字
    public void sendGetNumber(String text, int def, int min, int max) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalkNum(npc, text, def, min, max));
    }

    //显示一个要求玩家输入文本的弹出界面 txt是文字内容
    public void sendGetText(String text) {
        getClient().getSession().write(MaplePacketCreator.getNPCTalkText(npc, text));
    }

    //得到玩家输入的文字内容
    public void setGetText(String text) {
        this.getText = text;
    }

    //重新设置玩家输入文字内容
    public String getText() {
        return this.getText;
    }

    //关闭指定地图的某个传送点 cm.closePortal(地图ID, "[传送点名称]")
    public void closePortal(int mapid, String pName) {
        getClient().getChannelServer().getMapFactory().getMap(mapid).getPortal(pName).setPortalState(false);
    }

    //打开指定地图的某个传送点 cm.openPortal(地图ID, "[传送点名称]")
    public void openPortal(int mapid, String pName) {
        getClient().getChannelServer().getMapFactory().getMap(mapid).getPortal(pName).setPortalState(true);
    }

    //赠送成对效果的戒指给指定玩家 cm.makeRing("[玩家角色名]", 戒指ID)
    //public void makeRing(String partner, int ringId) {
    //    net.sf.odinms.client.MapleRing.createRing(ringId, c.getPlayer(), c.getChannelServer().getPlayerStorage().getCharacterByName(partner));
    //}

    //关闭指定的地图门 cm.closeDoor(地图ID) 好像老扎门口/闹钟门口用的比较多
    public void closeDoor(int mapid) {
        getClient().getChannelServer().getMapFactory().getMap(mapid).setReactorState();
    }

    //打开指定的地图门 cm.openDoor(地图ID) 好像老扎门口/闹钟门口用的比较多
    public void openDoor(int mapid) {
        getClient().getChannelServer().getMapFactory().getMap(mapid).resetReactors();
    }

    //打开指定的商店 cm.openShop(商店ID)
    public void openShop(int id) {
        MapleShopFactory.getInstance().getShop(id).sendShop(getClient());
    }

    //打开指定的NPC对话 cm.openNpc(NPCID)
    public void openNpc(int id) {
        dispose();
        NPCScriptManager.getInstance().start(getClient(), id, null, null);
    }

        //判断整个组队的所有成员是否在当前地图里 cm.isPartyAllHere()
    public boolean isPartyAllHere() {
        int num = 0;
        int myparty = 0;
        while (getPlayer().getParty().getMembers().iterator().hasNext()) {
            MaplePartyCharacter curChar = getPlayer().getParty().getMembers().iterator().next();
            if (curChar.isOnline()) {
                num += 1;
            }
        }
        while (getPlayer().getMap().getCharacters().iterator().hasNext()) {
            MapleCharacter curChar2 = getPlayer().getMap().getCharacters().iterator().next();
            if (curChar2.getParty() == getPlayer().getParty()) {
                myparty += 1;
            }
        }
        return num == myparty;
    }
    //改变玩家职业 cm.changeJob(职业)

    public void changeJob(MapleJob job) {
        getPlayer().changeJob(job);
    }
    //得到玩家职业 cm.getJob()

    public MapleJob getJob() {
        return getPlayer().getJob();
    }
    //开始一个任务 cm.startQuest(任务ID) 这里是原版游戏的任务ID，通过WZ里查询。

    public void startQuest(int id) {
        MapleQuest.getInstance(id).start(getPlayer(), npc);
    }
    //完成一个任务 cm.completeQuest(任务ID)

    public void completeQuest(int id) {
        MapleQuest.getInstance(id).complete(getPlayer(), npc);
    }
    //解除一个任务 cm.forfeitQuest(任务ID)

    public void forfeitQuest(int id) {
        MapleQuest.getInstance(id).forfeit(getPlayer());
    }

    //取得玩家当前背包金币数量值 cm.getMeso()
    @Deprecated
    public int getMeso() {
        return getPlayer().getMeso();
    }
    //给予或取走玩家指定数量金币 cm.gainMeso(钱数) 注意这里钱数如果是负数，那么是取走玩家的钱

    public void gainMeso(int gain) {
        getPlayer().gainMeso(gain, true, false, true);
    }
    //给予或取走玩家指定数量经验值 cm.gainExp(经验数) 注意这里经验数如果是负数，那么是扣掉玩家的经验数

    public void gainExp(int gain) {
        getPlayer().gainExp(gain, true, true);
    }
    //返回当前的NPC

    public int getNpc() {
        return npc;
    }

    //取得玩家当前的角色等级值 cm.getLevel()
    @Deprecated
    public int getLevel() {
        return getPlayer().getLevel();
    }
    //卸载戴在玩家身上的所有物品 cm.unequipEverything()

    public void unequipEverything() {
        MapleInventory equipped = getPlayer().getInventory(MapleInventoryType.EQUIPPED);
        MapleInventory equip = getPlayer().getInventory(MapleInventoryType.EQUIP);
        List<Byte> ids = new LinkedList<Byte>();
        for (IItem item : equipped.list()) {
            ids.add(item.getPosition());
        }
        for (byte id : ids) {
            MapleInventoryManipulator.unequip(getC(), id, equip.getNextFreeSlot());
        }
    }
    //让玩家学会指定技能 cm.teachSkill([技能id],[技能当前级别],[技能最大级别]);

    public void teachSkill(int id, int level, int masterlevel) {
        getPlayer().changeSkillLevel(SkillFactory.getSkill(id), level, masterlevel);
    }
    //清理玩家所学会的所有技能 cm.clearSkills()  转生时候要用的

    public void clearSkills() {
        Map<ISkill, MapleCharacter.SkillEntry> skills = getPlayer().getSkills();
        for (Entry<ISkill, MapleCharacter.SkillEntry> skill : skills.entrySet()) {
            getPlayer().changeSkillLevel(skill.getKey(), 0, 0);
        }
    }
    //得到玩家角色数据

    public MapleCharacter getChar() {
        return getPlayer();
    }
    //得到玩家客户端数据

    public MapleClient getC() {
        return getClient();
    }
    //得到玩家所在地图ID

    public int getmapid() {
        return getPlayer().getMapId();
    }
    //得到玩家是否在BOSS地图

    public boolean isBossMap() {
        return getPlayer().isBossMap();
    }

    public void rechargeStars() {
        MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
        IItem stars = getPlayer().getInventory(MapleInventoryType.USE).getItem((byte) 1);
        if (ii.isThrowingStar(stars.getItemId()) || ii.isBullet(stars.getItemId())) {
            stars.setQuantity(ii.getSlotMax(stars.getItemId()));
            getC().getSession().write(MaplePacketCreator.updateInventorySlot(MapleInventoryType.USE, (Item) stars));
        }
    }

    public EventManager getEventManager(String event) {
        return getClient().getChannelServer().getEventSM().getEventManager(event);
    }

    //得到玩家显示效果？cm.showEffect(String effect)
    public void showEffect(String effect) {
        getPlayer().getMap().broadcastMessage(MaplePacketCreator.showEffect(effect));
    }

    //在当前地图播放音乐 cm.playSound(String sound)
    public void playSound(String sound) {
        getClient().getPlayer().getMap().broadcastMessage(MaplePacketCreator.playSound(sound));
    }

    @Override
    public String toString() {
        return "您当前对话的NPC是：" + npc;
    }

    //增加或减少好友最大容量 cm.updateBuddyCapacity(好友数) 这里注意，如果是负数就是减少好友最大容量
    public void updateBuddyCapacity(int capacity) {
        getPlayer().setBuddyCapacity(capacity);
    }

    //达到玩家当前的好友最大容量数 cm.getBuddyCapacity()
    public int getBuddyCapacity() {
        return getPlayer().getBuddyCapacity();
    }

    //设置当前玩家的角色发型 cm.setHair(发型ID) 在发廊用
    public void setHair(int hair) {
        getPlayer().setHair(hair);
        getPlayer().updateSingleStat(MapleStat.HAIR, hair);
        getPlayer().equipChanged();
    }

    //设置当前玩家的角色脸型 cm.setFace(脸型ID) 在整容用
    public void setFace(int face) {
        getPlayer().setFace(face);
        getPlayer().updateSingleStat(MapleStat.FACE, face);
        getPlayer().equipChanged();
    }

    //设置当前玩家的角色肤色 cm.setSkin(肤色ID) 在美容用
    @SuppressWarnings("static-access")
    public void setSkin(int color) {
        getPlayer().setSkinColor(c.getPlayer().getSkinColor().getById(color));
        getPlayer().updateSingleStat(MapleStat.SKIN, color);
        getPlayer().equipChanged();
    }

    //传送当前玩家所在组队的所有成员到指定地图 cm.warpParty(地图ID)
    public void warpParty(int mapId) {
        for (MaplePartyCharacter chr : getPlayer().getParty().getMembers()) {
            MapleCharacter curChar = c.getChannelServer().getPlayerStorage().getCharacterByName(chr.getName());
            if ((curChar.getEventInstance() == null && c.getPlayer().getEventInstance() == null) || curChar.getEventInstance() == getPlayer().getEventInstance()) {
                curChar.changeMap(getMap(mapId), getMap(mapId).getPortal(0));
            }
        }
    }

    //传送当前玩家所在组队的所有成员到指定地图并给予经验值 cm.warpPartyWithExp(地图ID，经验值) 一般是通关后的奖励经验
    public void warpPartyWithExp(int mapId, int exp) {
        warpPartyWithExpMeso(mapId, exp, 0);
    }

    //传送当前玩家所在组队的所有成员到指定地图并给予经验值和游戏币 cm.warpPartyWithExpMeso(地图ID，经验值,游戏币) 一般是通关后的奖励经验
    public void warpPartyWithExpMeso(int mapId, int exp, int meso) {
        for (MaplePartyCharacter chr : getPlayer().getParty().getMembers()) {
            MapleCharacter curChar = c.getChannelServer().getPlayerStorage().getCharacterByName(chr.getName());
            if ((curChar.getEventInstance() == null && c.getPlayer().getEventInstance() == null) || curChar.getEventInstance() == getPlayer().getEventInstance()) {
                curChar.changeMap(getMap(mapId), getMap(mapId).getPortal(0));
                curChar.gainExp(exp, true, false, true);
                curChar.gainMeso(meso, false); //which pq has mesos?
            }
        }
    }

    //传送玩家到一个地图的随机位置 cm.warpRandom(地图ID)
    public void warpRandom(int mapid) {
        MapleMap target = c.getChannelServer().getMapFactory().getMap(mapid);
        getPlayer().changeMap(target, target.getPortal(new Random().nextInt(target.getPortals().size())));
    }

    //得到当前玩家背包里某种物品的数量 cm.itemQuantity(物品id)
    public int itemQuantity(int itemid) {
        return getPlayer().getInventory(MapleItemInformationProvider.getInstance().getInventoryType(itemid)).countById(itemid);
    }

    //为当前玩家开设一个远征队伍 cm.createMapleSquad(MapleSquadType type)
    public MapleSquad createMapleSquad(MapleSquadType type) {
        MapleSquad squad = new MapleSquad(c.getChannel(), getPlayer());
        if (getSquadState(type) == 0) {
            c.getChannelServer().addMapleSquad(squad, type);
        } else {
            return null;
        }
        return squad;
    }

    //得到当前玩家指定索引的远征队伍成员数据 cm.getSquadMember(MapleSquadType type, int index)
    public MapleCharacter getSquadMember(MapleSquadType type, int index) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        MapleCharacter ret = null;
        if (squad != null) {
            ret = squad.getMembers().get(index);
        }
        return ret;
    }

    /*
    Con.2022090.name 精灵威科的祝福 精灵威科给的祝福魔法。攻击力与魔力上升
    Con.2022091.name 精灵威科的祝福 精灵威科给的祝福魔法。物理防御力与魔法防御力上升
    Con.2022092.name 精灵威科的祝福 精灵威科给的祝福魔法。命中率与回避率上升
    Con.2022093.name 精灵威科的祝福 精灵威科给的祝福魔法。移动速度与跳跃力上升
     */
    //给予当前玩家物品效果 cm.giveWonkyBuff(角色)
    public void giveWonkyBuff(MapleCharacter chr) {
        int Buffs[] = {2022090, 2022091, 2022092, 2022093};
        MapleItemInformationProvider.getInstance().getItemEffect(Buffs[(int) Math.round(Math.random() * 4)]).applyTo((MapleCharacter) chr);
    }

    //得到当前玩家开设的远征队伍状态 cm.getSquadState(MapleSquadType type)
    public int getSquadState(MapleSquadType type) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        if (squad != null) {
            return squad.getStatus();
        } else {
            return 0;
        }
    }

    //设置当前玩家开设的远征队伍状态 cm.setSquadState(MapleSquadType type)
    public void setSquadState(MapleSquadType type, int state) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        if (squad != null) {
            squad.setStatus(state);
        }
    }

    //检测当前玩家是否为开设远征队伍的队长 cm.checkSquadLeader(MapleSquadType type)
    public boolean checkSquadLeader(MapleSquadType type) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        if (squad != null) {
            return squad.getLeader().getId() == getPlayer().getId();
        } else {
            return false;
        }
    }

    //删除当前玩家开设的远征队伍 cm.removeMapleSquad(MapleSquadType type)
    public void removeMapleSquad(MapleSquadType type) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        if (squad != null) {
            if (squad.getLeader().getId() == getPlayer().getId()) {
                squad.clear();
                c.getChannelServer().removeMapleSquad(squad, type);
            }
        }
    }

    //得到当前玩家的远征队伍成员总数 cm.numSquadMembers(MapleSquadType type)
    public int numSquadMembers(MapleSquadType type) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        int ret = 0;
        if (squad != null) {
            ret = squad.getSquadSize();
        }
        return ret;
    }
    //判断当前玩家是否是远征队伍成员 cm.isSquadMember(MapleSquadType type)

    public boolean isSquadMember(MapleSquadType type) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        boolean ret = false;
        if (squad.containsMember(getPlayer())) {
            ret = true;
        }
        return ret;
    }
    //增加当前玩家的远征队伍成员 cm.addSquadMember(MapleSquadType type)

    public void addSquadMember(MapleSquadType type) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        if (squad != null) {
            squad.addMember(getPlayer());
        }
    }
    //删除当前玩家的远征队伍成员(通过角色) cm.removeSquadMember(MapleSquadType type, MapleCharacter chr, boolean ban)

    public void removeSquadMember(MapleSquadType type, MapleCharacter chr, boolean ban) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        if (squad != null) {
            squad.banMember(chr, ban);
        }
    }
    //删除当前玩家的远征队伍成员(通过队伍索引) cm.removeSquadMember(MapleSquadType type, int index, boolean ban)

    public void removeSquadMember(MapleSquadType type, int index, boolean ban) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        if (squad != null) {
            MapleCharacter chr = squad.getMembers().get(index);
            squad.banMember(chr, ban);
        }
    }
    //判断当前玩家是否能够加入一个远征队伍成员 cm.canAddSquadMember(MapleSquadType type)

    public boolean canAddSquadMember(MapleSquadType type) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        if (squad != null) {
            return !squad.isBanned(getPlayer());
        }
        return false;
    }
    //第2页
    //传送当前玩家所在远征队伍所有成员到指定地图 cm.warpSquadMembers(MapleSquadType type, int mapId)

    public void warpSquadMembers(MapleSquadType type, int mapId) {
        MapleSquad squad = c.getChannelServer().getMapleSquad(type);
        MapleMap map = c.getChannelServer().getMapFactory().getMap(mapId);
        if (squad != null) {
            if (checkSquadLeader(type)) {
                for (MapleCharacter chr : squad.getMembers()) {
                    chr.changeMap(map, map.getPortal(0));
                }
            }
        }
    }

    //为当前玩家创建成对戒指 cm.makeRing(MapleClient c, 对方角色名, 戒指ID)
    //public static boolean makeRing(MapleClient c, String partner, int ringId) {
    //    int ret = net.sf.odinms.client.MapleRing.createRing(ringId, c.getPlayer(), c.getChannelServer().getPlayerStorage().getCharacterByName(partner));
    //    return ret == 1;
    //}


    //传送指定玩家到当前地图 cm.WarpTo(被传送对象角色名)
    public void WarpTo(String player) {
        MapleCharacter victim = c.getChannelServer().getPlayerStorage().getCharacterByName(player);
        getPlayer().changeMap(victim.getMap(), victim.getMap().findClosestSpawnpoint(victim.getPosition()));
    }
    //显示家族排行榜 cm.displayGuildRanks()

    public void displayGuildRanks() {
        MapleGuild.displayGuildRanks(getClient(), npc);
    }

    //显示人气排行榜 cm.displayfame()
    public void displayfame() {
        MapleGuild.displayfame(getClient(), npc);
    }

    //显示转生排行榜 cm.displayReborns()
    public void displayReborns() {
        MapleGuild.displayReborns(getClient(), npc);
    }

    //打开邮递员对话 cm.openDuey()
    //public void openDuey() {
   //     c.getSession().write(MaplePacketCreator.sendDueyAction((byte) 8));
    //}

    //改变当前玩家的角色性别 cm.changeSex() 男女转换
    public void changeSex() {
        getPlayer().setGender(1 - getPlayer().getGender());
        getClient().getSession().write(MaplePacketCreator.updateCharLook(getPlayer()));
    }

    //得到当前玩家的宠物等级 cm.getPetLevel()
    public int getPetLevel() {
        for (MaplePet pet : getPlayer().getPets()) {
            return pet.getLevel();
        }
        return 0;
    }

    //得到当前玩家的宠物亲密度 cm.getFullness()
    public int getFullness() {
        for (MaplePet pet : getPlayer().getPets()) {
            return pet.getFullness();
        }
        return 0;
    }

    //得到当前玩家的宠物名称 cm.getPetName()
    public String getPetName() {
        for (MaplePet pet : getPlayer().getPets()) {
            return pet.getName();
        }
        return "";
    }
    //修改当前玩家的宠物名称 cm.getPetName("[新宠物名]")

    public void setPetName(String petname) {
        for (MaplePet pet : getPlayer().getPets()) {
            pet.setName(petname);
        }
    }
    //得到当前游戏频道数据 cm.getChannelServer()

    public ChannelServer getChannelServer() {
        return cserv;
    }

    public void startQuest(int id, MapleClient cg) {
        MapleQuest.getInstance(id).start(cg.getPlayer(), npc);
    }

    public void completeQuest(int id, MapleClient cg) {
        MapleQuest.getInstance(id).complete(cg.getPlayer(), npc);
    }

    public void forfeitQuest(int id, MapleClient cg) {
        MapleQuest.getInstance(id).forfeit(cg.getPlayer());
    }

    //得到当前玩家的组队数据 cm.getParty()
    @Override
    public MapleParty getParty() {
        return getPlayer().getParty();
    }
    //刷出指定数量的怪物 cm.summonMob(怪物ID, 怪物HP, 经验值, 刷怪数量)

    public void summonMob(int mobid, int customHP, int customEXP, int amount) {
        spawnMonster(mobid, customHP, -1, -1, customEXP, 0, 0, amount, getPlayer().getPosition().x, getPlayer().getPosition().y);
    }
    //修改当前玩家的角色等级 cm.setLevel(级别数) 级别数不允许是负数且小于250，否则会出错。

    public void setLevel(int level) {
        getPlayer().setLevel(level);
        getPlayer().updateSingleStat(MapleStat.LEVEL, Integer.valueOf(level));
    }
    //刷出指定数量的怪物（高级）cm.spawnMonster(怪物ID, 怪物HP, 怪物MP, 怪物等级, 怪物经验, 是否BOSS, 是否为不死怪, 刷怪数量, 怪物横坐标, 怪物纵坐标)

    public void spawnMonster(int mobid, int HP, int MP, int level, int EXP, int boss, int undead, int amount, int x, int y) {
        MapleMonsterStats newStats = new MapleMonsterStats();
        if (HP > 0) {
            newStats.setHp(HP);
        }
        if (MP > 0) {
            newStats.setMp(MP);
        }
        if (level > 0) {
            newStats.setLevel(level);
        }
        if (EXP > 0) {
            newStats.setExp(EXP);
        }
        newStats.setBoss(boss == 1);
        newStats.setUndead(undead == 1);
        for (int i = 0; i < amount; i++) {
            MapleMonster npcmob = MapleLifeFactory.getMonster(mobid);
            npcmob.setOverrideStats(newStats);
            npcmob.setHp(npcmob.getMaxHp());
            npcmob.setMp(npcmob.getMaxMp());
            getPlayer().getMap().spawnMonsterOnGroundBelow(npcmob, new Point(x, y));
        }
    }
    //刷出指定数量的怪物（简单1） cm.summonMob(怪物id,地图ID,怪物移动的横坐标范围, 怪物移动的纵坐标范围)

    public void spawnMob(int mapid, int mid, int xpos, int ypos) {
        getClient().getChannelServer().getMapFactory().getMap(mapid).spawnMonsterOnGroudBelow(MapleLifeFactory.getMonster(mid), new Point(xpos, ypos));
    }

    //刷出指定数量的怪物（简单2） cm.summonMob(怪物id)
    public void summonMob(int mobid) {
        getPlayer().getMap().spawnMonsterOnGroudBelow(MapleLifeFactory.getMonster(mobid), getNPCPosition());
    }
    //刷出指定数量的怪物（高级控制1）cm.summonMobAtPosition(怪物id, 怪物HP, 怪物经验, 刷怪数量, 怪物移动的横坐标范围, 怪物移动的纵坐标范围)

    public void summonMobAtPosition(int mobid, int customHP, int customEXP, int amount, int posx, int posy) {
        MapleMonsterStats newStats = new MapleMonsterStats();
        if (customHP > 0) {
            newStats.setHp(customHP);
        }
        if (customEXP >= 0) {
            newStats.setExp(customEXP);
        }
        if (amount < 2) {
            MapleMonster npcmob = MapleLifeFactory.getMonster(mobid);
            npcmob.setOverrideStats(newStats);
            npcmob.setHp(npcmob.getMaxHp());
            getPlayer().getMap().spawnMonsterOnGroudBelow(npcmob, new Point(posx, posy));
        } else {
            for (int i = 0; i < amount; i++) {
                MapleMonster npcmob = MapleLifeFactory.getMonster(mobid);
                npcmob.setOverrideStats(newStats);
                npcmob.setHp(npcmob.getMaxHp());
                getPlayer().getMap().spawnMonsterOnGroudBelow(npcmob, new Point(posx, posy));
            }
        }
    }
    //刷出指定数量的怪物（高级控制2）cm.summonMobAtPosition(怪物id, 刷怪数量, 怪物移动的横坐标范围, 怪物移动的纵坐标范围)

    public void summonMobAtPosition(int mobid, int amount, int posx, int posy) {
        if (amount <= 1) {
            MapleMonster npcmob = MapleLifeFactory.getMonster(mobid);
            npcmob.setHp(npcmob.getMaxHp());
            getPlayer().getMap().spawnMonsterOnGroudBelow(npcmob, new Point(posx, posy));
        } else {
            for (int i = 0; i < amount; i++) {
                MapleMonster npcmob = MapleLifeFactory.getMonster(mobid);
                npcmob.setHp(npcmob.getMaxHp());
                getPlayer().getMap().spawnMonsterOnGroudBelow(npcmob, new Point(posx, posy));
            }
        }
    }
    //杀死玩家当前地图里的所有怪物 cm.killAllMobs() 一般用来做任务清场

    public void killAllMobs() {
        MapleMap map = getPlayer().getMap();
        double range = Double.POSITIVE_INFINITY;
        List<MapleMapObject> monsters = map.getMapObjectsInRange(getPlayer().getPosition(), range, Arrays.asList(MapleMapObjectType.MONSTER));
        for (MapleMapObject monstermo : monsters) {
            map.killMonster((MapleMonster) monstermo, getPlayer(), false);
        }
    }
    //当前玩家的角色升级1级且经验自动归零 cm.levelUp()

    public void levelUp() {
        getPlayer().levelUp();
        getPlayer().gainExp(-getPlayer().getExp(), false, false);
    }
    //设置当前玩家的角色剩余能力值 cm.setAP(能力值) 能力值必须为整数且大于零

    public void setAP(int AP) {
        getPlayer().setRemainingAp(AP);
        getPlayer().updateSingleStat(MapleStat.AVAILABLEAP, Integer.valueOf(AP));
    }
    //给予或扣除当前玩家的角色剩余能力值 cm.gainAP(能力值) 能力值如果是负数就是扣除能力剩余能力点

    public void gainAP(int g) {
        getPlayer().setRemainingAp(g + getPlayer().getRemainingAp());
        getPlayer().updateSingleStat(MapleStat.AVAILABLEAP, Integer.valueOf(g + getPlayer().getRemainingAp()));
    }
    //设置当前玩家的角色剩余技能值 cm.setAP(技能值) 技能值必须为整数且大于零

    public void setSP(int SP) {
        getPlayer().setRemainingSp(SP);
        getPlayer().updateSingleStat(MapleStat.AVAILABLESP, Integer.valueOf(SP));
    }
    //设置当前玩家的角色力量值 cm.setStr(数值) 数值必须为整数且大于零

    public void setStr(int str) {
        getPlayer().setStr(str);
        getPlayer().updateSingleStat(MapleStat.STR, Integer.valueOf(str));
    }
    //设置当前玩家的角色敏捷值 cm.setDex(数值) 数值必须为整数且大于零

    public void setDex(int dex) {
        getPlayer().setDex(dex);
        getPlayer().updateSingleStat(MapleStat.DEX, Integer.valueOf(dex));
    }
    //设置当前玩家的角色智力值 cm.setInt(数值) 数值必须为整数且大于零

    public void setInt(int inte) {
        getPlayer().setInt(inte);
        getPlayer().updateSingleStat(MapleStat.INT, Integer.valueOf(inte));
    }

    //设置当前玩家的角色运气值 cm.setLuk(数值) 数值必须为整数且大于零
    public void setLuk(int luk) {
        getPlayer().setLuk(luk);
        getPlayer().updateSingleStat(MapleStat.LUK, Integer.valueOf(luk));
    }

    //判断当前玩家是否为当前组队的队长 cm.isPartyLeader()
    public boolean isPartyLeader() {
        return getPlayer().isPartyLeader();
    }

    //设置当前玩家的角色人气值 cm.setFame(数值) 数值必须为整数且大于零
    public void setFame(int fame) {
        getPlayer().setFame(fame);
        getPlayer().updateSingleStat(MapleStat.FAME, Integer.valueOf(fame));
    }

    //设置当前玩家的角色经验值 cm.setExp(数值) 数值必须为整数且大于零
    public void setExp(int exp) {
        getPlayer().updateSingleStat(MapleStat.EXP, Integer.valueOf(exp));
    }

    //刷新指定地图的数据信息 cm.resetMap(地图id)
    @Override
    public void resetMap(int mapid) {
        getClient().getChannelServer().getMapFactory().getMap(mapid).resetReactors();
    }
    //刷新环境信息 cm.environmentChange(String env, int mode)

    public void environmentChange(String env, int mode) {
        getPlayer().getMap().broadcastMessage(MaplePacketCreator.environmentChange(env, mode));
    }
    //得到当前地图的玩家人数 cm.getCharsOnMap() 非常有用，可以在任务中限制参与人数。

    public int getCharsOnMap() {
        return getPlayer().getMap().getCharacters().size();
    }
    //得到服务器当前时间的星期几 cm.getDayOfWeek()

    public int getDayOfWeek() {
        return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
    }
    //得到服务器当前时间的星期几 cm.getDay()

    public int getDay() {
        return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
    }
    //得到服务器当前时间的小时数 cm.getHour()

    public int getHour() {
        return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
    }
    //得到服务器当前时间的分钟数 cm.getMin()

    public int getMin() {
        return Calendar.getInstance().get(Calendar.MINUTE);
    }
    //得到服务器当前时间的秒数 cm.getSec()

    public int getSec() {
        return Calendar.getInstance().get(Calendar.SECOND);
    }
    //杀死指定地图的所有怪物 cm.killAllMonster(地图id)

    public void killAllMonster(int mapid) {
        getClient().getChannelServer().getMapFactory().getMap(mapid).killAllMonsters(true);
    }
    //使当前玩家获得指定技能效果 cm.giveBuff(int buff, int level)

    public void giveBuff(int buff, int level) {
        SkillFactory.getSkill(buff).getEffect(level).applyTo(getPlayer());
    }
    //hairi 禁止NPC提升管理员权限
    //public void setGMLevel(int l) {
    //    getPlayer().setGMLevel(l);
    //}
    //给予或扣除当前玩家的角色宠物亲密度 cm.gainCloseness(亲密值) 亲密值如果是负数就是扣除亲密度

    public void gainCloseness(int closeness) {
        for (MaplePet pet : getPlayer().getPets()) {
            if (pet.getCloseness() < 30000 || pet.getLevel() < 30) {
                if ((pet.getCloseness() + closeness) > 30000) {
                    pet.setCloseness(30000);
                } else {
                    pet.setCloseness(pet.getCloseness() + closeness);
                }
                while (pet.getCloseness() > ExpTable.getClosenessNeededForLevel(pet.getLevel() + 1)) {
                    pet.setLevel(pet.getLevel() + 1);
                    getClient().getSession().write(MaplePacketCreator.showOwnPetLevelUp(getPlayer().getPetIndex(pet)));
                }
                getPlayer().getClient().getSession().write(MaplePacketCreator.updatePet(pet, true));
            }
        }
    }
    //得到当前NPC坐标位置 cm.getNPCPosition()

    public Point getNPCPosition() {
        MapleNPC thenpc = MapleLifeFactory.getNPC(this.npc);
        Point pos = thenpc.getPosition();
        return pos;
    }
    //得到当前玩家坐标位置 cm.getPosition()

    public Point getPosition() {
        Point pos = getPlayer().getPosition();
        return pos;
    }
    //给予玩家物品效果 cm.giveItemBuff(物品Id) 这里可以让玩家吃一个药水或啥的，自己想。

    public void giveItemBuff(int itemId) {
        getPlayer().setItemEffect(itemId);
    }
    //判断玩家当前是否处于变身状态 cm.isMorphed()

    public boolean isMorphed() {
        boolean morph = false;
        if (getPlayer().getBuffedValue(MapleBuffStat.MORPH) != null) {
            morph = true;
        }
        return morph;
    }
    //得到当前玩家的角色变身值 cm.getMorphValue()

    public int getMorphValue() {
        try {
            int morphid = getPlayer().getBuffedValue(MapleBuffStat.MORPH).intValue();
            return morphid;
        } catch (NullPointerException n) {
            return -1;
        }
    }
    //得到当前玩家在频道中远征队伍数据 cm.getSquad(MapleSquadType Type)

    public MapleSquad getSquad(MapleSquadType Type) {
        return c.getChannelServer().getMapleSquad(Type);
    }

    //刷新当前玩家所在地图的数据 cm.resetReactors()
    public void resetReactors() {
        getPlayer().getMap().resetReactors();
    }

    //刷新当前玩家所在地图的数据带清理所有怪物 cm.resetReactorsFull()
    public void resetReactorsFull() {
        getPlayer().getMap().killAllMonster();
        getPlayer().getMap().resetReactors();
    }

    //设置当前玩家的角色HP值，cm.setHp(数值) 数值必须大于零且不能是负数
    public void setHp(int hp) {
        getPlayer().setHp(hp);
    }

    //设置当前玩家的角色MP值，cm.setMp(数值) 数值必须大于零且不能是负数
    public void setMp(int mp) {
        getPlayer().setMp(mp);
    }

    //增加或扣除当前玩家的角色HP值，cm.addHp(数值) 数值是负数表示扣除
    public void addHp(int hp) {
        getPlayer().addHP(hp);
    }

    //增加或扣除当前玩家的角色MP值，cm.addMp(数值) 数值是负数表示扣除
    public void addMp(int mp) {
        getPlayer().addMP(mp);
    }

    //增加或扣除当前玩家的宠物的亲密值，cm.addCloseness(数值) 数值是负数表示扣除
    public void addCloseness(int increase) {
        MaplePet pet = getPlayer().getPet(0);
        if (pet.getCloseness() < 30000) {
            int newCloseness = pet.getCloseness() + increase;
            if (newCloseness > 30000) {
                newCloseness = 30000;
            }
            pet.setCloseness(newCloseness);
            if (newCloseness >= ExpTable.getClosenessNeededForLevel(pet.getLevel() + 1)) {
                pet.setLevel(pet.getLevel() + 1);
                c.getSession().write(MaplePacketCreator.showPetLevelUp(getPlayer(), 0));
            }
            c.getSession().write(MaplePacketCreator.updatePet(pet, true));
        }
    }

    //得到玩家的角色名 cm.getName()  这样做的NPC对话的友好性更出色
    public String getName() {
        return getPlayer().getName();
    }

    //得到玩家的角色性别 cm.getGender() 0,男 1,女
    public int getGender() {
        return getPlayer().getGender();
    }

    //得到当前玩家所在地图的怪物总数 cm.countMonster() 做打怪任务时判断很好用
    public int countMonster() {
        return getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.MONSTER)).size();
    }

    //得到当前玩家所在地图的掉物总数 cm.countReactor()
    public int countReactor() {
        return getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.REACTOR)).size();
    }

    //得到当前玩家所在地图的玩家数 cm.countPlayer()
    public int countPlayer() {
        return getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER)).size();
    }

    //给予指定玩家指定的物品效果 cm.giveNPCBuff(角色, 物品ID)
    public void giveNPCBuff(MapleCharacter chr, int itemID) {
        MapleItemInformationProvider.getInstance().getItemEffect(itemID).applyTo(chr);
    }

    //传送所有玩家到指定地图的指定传送点位置 cm.warpAllInMap(地图id, 传送点数值)
    public void warpAllInMap(int mapid, int portal) {
        MapleMapFactory mapFactory = ChannelServer.getInstance(c.getChannel()).getMapFactory();
        MapleMap outMap = mapFactory.getMap(mapid);
        for (MapleCharacter aaa : outMap.getCharacters()) {
            mapFactory = ChannelServer.getInstance(aaa.getClient().getChannel()).getMapFactory();//hmmm needed?
            aaa.getClient().getPlayer().changeMap(outMap, outMap.getPortal(portal));
            outMap = mapFactory.getMap(mapid);//hmmm needed?
            aaa.getClient().getPlayer().getEventInstance().unregisterPlayer(aaa.getClient().getPlayer());
        }
    }

    //通过角色名得到角色数据 cm.getCharByName(角色名)
    public MapleCharacter getCharByName(String name) {
        try {
            return getClient().getChannelServer().getPlayerStorage().getCharacterByName(name);
        } catch (Exception e) {
            return null;
        }
    }

    //判断当前玩家是否开有雇佣商店
    //public boolean hasMerchant() {
    //    return getPlayer().hasMerchant();
    //}

    //删除指定ID的雇佣商店物品 cm.removeHiredMerchantItem(id)
    public void removeHiredMerchantItem(int id) {
        try {
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("DELETE FROM hiredmerchant WHERE id = ?");
            ps.setInt(1, id);
            ps.executeUpdate();
            ps.close();
        } catch (SQLException se) {
        }
    }
    //清理玩家雇佣商店里所有数据库物品
    public void removeHiredMerchantAllItem(int charid) {
        try {
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("DELETE FROM hiredmerchant WHERE ownerid = ?");
            ps.setInt(1, charid);
            ps.executeUpdate();
            ps.close();
        } catch (SQLException se) {
        }
    }

    public int getHiredMerchantMesos() {
        int mesos;
        try {
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT MerchantMesos FROM characters WHERE id = ?");
            ps.setInt(1, getPlayer().getId());
            ResultSet rs = ps.executeQuery();
            rs.next();
            mesos = rs.getInt("MerchantMesos");
            rs.close();
            ps.close();
        } catch (SQLException se) {
            return 0;
        }
        return mesos;
    }

    public void zeroMerchantMesos() {
        try {
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("UPDATE characters SET MerchantMesos = 0 WHERE id = ?");
            ps.setInt(1, getPlayer().getId());
            ps.executeUpdate();
            ps.close();
        } catch (SQLException se) {
        }
    }

    public List<Pair<Integer, IItem>> getHiredMerchantItems() {
        List<Pair<Integer, IItem>> items = new ArrayList<Pair<Integer, IItem>>();
        try {
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM hiredmerchant WHERE ownerid = ?");
            ps.setInt(1, getPlayer().getId());
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                if (rs.getInt("type") == 1) {
                    Equip eq = new Equip(rs.getInt("itemid"), (byte) 0, -1);
                    eq.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
                    eq.setLevel((byte) rs.getInt("level"));
                    eq.setStr((short) rs.getInt("str"));
                    eq.setDex((short) rs.getInt("dex"));
                    eq.setInt((short) rs.getInt("int"));
                    eq.setLuk((short) rs.getInt("luk"));
                    eq.setHp((short) rs.getInt("hp"));
                    eq.setMp((short) rs.getInt("mp"));
                    eq.setWatk((short) rs.getInt("watk"));
                    eq.setMatk((short) rs.getInt("matk"));
                    eq.setWdef((short) rs.getInt("wdef"));
                    eq.setMdef((short) rs.getInt("mdef"));
                    eq.setAcc((short) rs.getInt("acc"));
                    eq.setAvoid((short) rs.getInt("avoid"));
                    eq.setHands((short) rs.getInt("hands"));
                    eq.setSpeed((short) rs.getInt("speed"));
                    eq.setJump((short) rs.getInt("jump"));
                    eq.setOwner(rs.getString("owner"));
                    items.add(new Pair<Integer, IItem>(rs.getInt("id"), eq));
                } else if (rs.getInt("type") == 2) {
                    Item newItem = new Item(rs.getInt("itemid"), (byte) 0, (short) rs.getInt("quantity"));
                    newItem.setOwner(rs.getString("owner"));
                    items.add(new Pair<Integer, IItem>(rs.getInt("id"), newItem));
                }
            }

            ps.close();
            rs.close();
        } catch (SQLException se) {
            return null;
        }
        return items;
    }

    //第3页
    //得到玩家职业代码 cm.getJobID()
    public int getJobID() {
        return getPlayer().getJobID();
    }

    //NPC卖人气 cm.gainFame(人气值) 人气值为负数时扣除当前人气值
    public void gainFame(int fame) {
        if (fame > 0) {
            getPlayer().getClient().getSession().write(MaplePacketCreator.serverNotice(6, "『 系统提示 』 您已经获得了 " + fame + " 点人气."));
        } else if (fame < 0) {
            getPlayer().getClient().getSession().write(MaplePacketCreator.serverNotice(6, "『 系统提示 』 您已经失去了 " + fame + " 点人气."));
        }
        getPlayer().gainFame(fame);
        getPlayer().updateSingleStat(MapleStat.FAME, Integer.valueOf(getPlayer().getFame()));
    }

    //NPC发红色字公告 cm.serverNotice("[公告]大家好。。。。。");
    public void serverNotice(String Text) {
        getClient().getChannelServer().broadcastPacket(MaplePacketCreator.serverNotice(6, Text));
    }

    //设置当前玩家的VIP等级 cm.setVip(等级) 1,初级，2，中级，3，高级
    public void setVip(int vip) {
        getPlayer().setVip(vip);
    }

    //得到当前玩家的VIP等级 cm.getVip()
    public int getVip() {
        return getPlayer().getVip();
    }

    //判断当前玩家是否是GM cm.isGM()
    public boolean isGM() {
        return getPlayer().isGM();
    }

    //判断当前玩家是否在会员频道 cm.isVipChannel()
    public boolean isVipChannel() {
        return getPlayer().isVipChannel();
    }

    //得到当前玩家的转生数 cm.getReborns()
    public int getReborns() {
        return getPlayer().getReborns();
    }

    //得到角色所在大区 cm.getWorld()
    public int getWorld() {
        return getPlayer().getWorld();
    }

    //给予或扣除当前玩家的点卷数 cm.gainNX(点卷数) 点卷数为负数就是扣点卷
    public void gainNX(int nxcash) {
        getPlayer().gainNX(nxcash);
    }

    //得到当前玩家拥有的点卷数 cm.getNX()
    public int getNX() {
        return getPlayer().getNX();
    }

    //高级任务系统 - 任务创建
    public void MissionMake(int npcid, int itemid, int repeat, int repeattime, int lockmap) {
        int charid;
        charid = getPlayer().getId();
        try {
            Connection con = DatabaseConnection.getConnection();
            PreparedStatement ps = con.prepareStatement("INSERT INTO mission VALUES (DEFAULT, ?, ?, ?, ?, ?, ?, 0, DEFAULT, 0)");
            ps.setInt(1, npcid);
            ps.setInt(2, charid);
            ps.setInt(3, itemid);
            ps.setInt(4, repeat);
            ps.setInt(5, repeattime);
            ps.setInt(6, lockmap);
            //ps.setInt(7, finish);
            //ps.setInt(8, lastdate);
            //ps.setInt(9, times);
            ps.executeUpdate();
            ps.close();
        } catch (SQLException ex) {
            log.error("Error MissionMake:", ex);
        }
    }

    //高级任务系统 - 重新做同一个任务
    public void MissionReMake(int npcid, int itemid, int repeat, int repeattime, int lockmap) {
        int charid;
        int finish;
        charid = getPlayer().getId();
        finish = 0;
        try {
            Connection con = DatabaseConnection.getConnection();
            PreparedStatement ps = con.prepareStatement("UPDATE mission SET `repeat` = ?, repeattime = ?, lockmap = ?, finish = ? WHERE npcid = ? and charid = ? and itemid = ?");
            ps.setInt(1, repeat);
            ps.setInt(2, repeattime);
            ps.setInt(3, lockmap);
            ps.setInt(4, finish);
            ps.setInt(5, npcid);
            ps.setInt(6, charid);
            ps.setInt(7, itemid);
            ps.executeUpdate();
            ps.close();
        } catch (SQLException ex) {
            log.error("Error MissionFinish:", ex);
        }
    }

    //高级任务系统 - 任务完成
    public void MissionFinish(int npcid, int itemid) {
        int charid;
        charid = getPlayer().getId();
        try {
            Connection con = DatabaseConnection.getConnection();
            PreparedStatement ps = con.prepareStatement("UPDATE mission SET finish = 1, lastdate = CURRENT_TIMESTAMP(), times = times+1, lockmap = 0 WHERE npcid = ? and charid = ? and itemid = ?");
            ps.setInt(1, npcid);
            ps.setInt(2, charid);
            ps.setInt(3, itemid);
            ps.executeUpdate();
            ps.close();
        } catch (SQLException ex) {
            log.error("Error MissionFinish:", ex);
        }
    }

    //高级任务系统 - 放弃任务
    public void MissionDelete(int npcid, int itemid) {
        int charid;
        charid = getPlayer().getId();
        try {
            Connection con = DatabaseConnection.getConnection();
            PreparedStatement ps = con.prepareStatement("DELETE FROM mission WHERE npcid = ? and charid = ? and itemid = ?");
            ps.setInt(1, npcid);
            ps.setInt(2, charid);
            ps.setInt(3, itemid);
            ps.executeUpdate();
            ps.close();
        } catch (SQLException ex) {
            log.error("Error MissionDelete:", ex);
        }
    }

    //高级任务系统 - 放弃所有未完成任务
    public void MissionDeleteNotFinish() {
        int charid;
        charid = getPlayer().getId();
        try {
            Connection con = DatabaseConnection.getConnection();
            PreparedStatement ps = con.prepareStatement("DELETE FROM mission WHERE finish = 0 and charid = ?");
            ps.setInt(1, charid);
            ps.executeUpdate();
            ps.close();
        } catch (SQLException ex) {
            log.error("Error MissionDeleteNotFinish:", ex);
        }
    }

    //高级任务系统 - 获得任务是否可以做
    public boolean MissionStatus(int npcid, int itemid, int maxtimes, int checktype) {
        // checktype
        // 0 检查此任务是否被完成了
        // 1 检查此任务是否允许重复做
        // 2 检查此任务重复做的时间间隔是否到
        // 3 检查此任务是否到达最大的任务次数
        // 4 检查是否接过此任务，即是否第一次做这个任务
        // 5 检查是否接了锁地图传送的任务
        boolean ret = false; //默认是可以做
        int MissionMake = 0; //默认是没有接过此任务
        long now = 0;
        long t = 0;
        Timestamp lastdate;
        int repeat = 0;
        int repeattime = 0;
        int finish = 0;
        int times = 0;
        int charid;
        charid = getPlayer().getId();
        try {
            PreparedStatement ps;
            Connection con = DatabaseConnection.getConnection();
            if (checktype == 5) {
                ps = con.prepareStatement("SELECT * FROM mission WHERE lockmap = 1 and charid = ?");
                ps.setInt(1, charid);
            } else {
                ps = con.prepareStatement("SELECT * FROM mission WHERE npcid = ? and charid = ? and itemid = ?");
                ps.setInt(1, npcid);
                ps.setInt(2, charid);
                ps.setInt(3, itemid);
            }
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                lastdate = rs.getTimestamp("lastdate");
                repeat = rs.getInt("repeat");
                repeattime = rs.getInt("repeattime");
                finish = rs.getInt("finish");
                times = rs.getInt("times");
                t = lastdate.getTime();
                now = System.currentTimeMillis();
                MissionMake = 1; //标明这个任务已经接过了
            }
            rs.close();
            ps.close();
            //判断检查状态类型
            switch (checktype) {
                case 0:
                    if (finish == 1) {
                        ret = true;
                    }
                    break;
                case 1:
                    if (repeat == 1) {
                        ret = true;
                    }
                    break;
                case 2:
                    if (now - t > repeattime) { // 判断如果有没有到指定的重复做任务间隔时间
                        //已经到了间隔时间
                        ret = true;
                    }
                    break;
                case 3:
                    if (times >= maxtimes) {
                        //任务到达最大次数
                        ret = true;
                    }
                    break;
                case 4:
                    if (MissionMake == 1) {
                        //此任务已经接过了
                        ret = true;
                    }
                    break;
                case 5:
                    if (MissionMake == 1) {
                        //已经接了锁地图的任务
                        ret = true;
                    }
            }
        } catch (SQLException ex) {
            log.error("Error MissionStatus:", ex);
        }
        return ret;
    }

    //清空当前玩家指定背包类型的所有物品 cm.deleteItem(类型数) 1,装备,2,消耗,3,设置,4,其他,5,点卷
    public void deleteItem(int inventorytype) {
        try {
            Connection con = DatabaseConnection.getConnection();
            PreparedStatement ps = con.prepareStatement("Select * from inventoryitems where characterid=? and inventorytype=?");
            ps.setInt(1, getPlayer().getId());
            ps.setInt(2, inventorytype);
            ResultSet re = ps.executeQuery();
            MapleInventoryType type = null;
            switch (inventorytype) {
                case 1:
                    type = MapleInventoryType.EQUIP;
                    break;
                case 2:
                    type = MapleInventoryType.USE;
                    break;
                case 3:
                    type = MapleInventoryType.SETUP;
                    break;
                case 4:
                    type = MapleInventoryType.ETC;
                    break;
                case 5:
                    type = MapleInventoryType.CASH;
                    break;
            }
            while (re.next()) {
                MapleInventoryManipulator.removeById(getC(), type, re.getInt("itemid"), 1, true, true);
            }
            re.close();
            ps.close();

        } catch (SQLException ex) {
            // Logger.getLogger(NPCConversationManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    //给予或扣除当前玩家的点卷数 cm.modifyNX(点卷数,点卷类型) 点卷数为负数就是扣点卷 0,1,点卷 2,抵用卷 3,奖励？
    public void modifyNX(int amount, int type) {
        getPlayer().modifyCSPoints(type, amount);
        if (amount > 0) {
            getClient().getSession().write(MaplePacketCreator.serverNotice(5, "『 系统提示 』 您已经获得了 " + amount + " 点商城点卷."));
        } else {
            getClient().getSession().write(MaplePacketCreator.serverNotice(5, "『 系统提示 』 您已经使用了 " + amount + " 点商城点卷."));
        }
    }

    //重新加载当前玩家的数据 先删除然后再添加 cm.reloadChar()
    public void reloadChar() {
        getPlayer().saveToDB(true); //更新数据
        getPlayer().getClient().getSession().write(MaplePacketCreator.getCharInfo(getPlayer()));
        getPlayer().getMap().removePlayer(getPlayer());
        getPlayer().getMap().addPlayer(getPlayer());
    }

    //剪刀石头布游戏里需要的随机整数
    public int getRandom(int start, int end) {
        return (int) Math.floor(Math.random() * end + start);
    }

    //得到1对1PK房间的角色数 cm.getCharQuantity(PK房间地图ID, 限制最低级别, 限制最高级别)
    public int getCharQuantity(int ismap, int minlevel, int maxlevel) {
        MapleMap map = c.getChannelServer().getMapFactory().getMap(ismap);
        double range = Double.POSITIVE_INFINITY;
        List<MapleMapObject> players = map.getMapObjectsInRange(c.getPlayer().getPosition(), range, Arrays.asList(MapleMapObjectType.PLAYER));
        if (players.size() <= 30 && ismap == 980000601) { //那个自由PK的房间，如果小于=30人时可以进入
            return 1; //返回1表示随时可以进入
        } else {
            if (c.getPlayer().getLevel() < minlevel || c.getPlayer().getLevel() > maxlevel) { //这里判断玩家级别是否满足房间要求
                return 2;//返回2表示已经战斗中，不允许加入。
            } else {
                return players.size();
            }
        }
    }

    //得到1对1PK房间的状态文本 cm.getPvpRoom(PK地图代码, 房间编号, 房间名称)
    public String getPvpRoom(int ismap, int sel, String roomname) { //ismap=PK地图代码 sel=房间编号
        MapleMap map = c.getChannelServer().getMapFactory().getMap(ismap);
        double range = Double.POSITIVE_INFINITY;
        List<MapleMapObject> players = map.getMapObjectsInRange(c.getPlayer().getPosition(), range, Arrays.asList(MapleMapObjectType.PLAYER));
        if (players.size() <= 0) {
            return "#L" + sel + "#" + roomname + " #r（创建）#k#l";
        } else if (players.size() == 1) {
            return "#L" + sel + "#" + roomname + " #b（等待）#k#l";
        } else if (players.size() >= 2) {
            return "#L" + sel + "#" + roomname + " #d（战斗）k#l";
        } else {
            return "";
        }
    }

    //发布1对1PK房间的公告信息 cm.Charnotice(公告类型, 公告内容)
    public void Charnotice(int type, String text) {
        c.getPlayer().getClient().getSession().write(MaplePacketCreator.serverNotice(type, text));
    }

    //结婚系统 - NPC创建两人结婚
    /*public boolean createMarriage(String partner_) {
        MapleCharacter partner = getCharByName(partner_);
        if (partner == null) {
            return false;
        }
        partner.setMarried(1);
        getPlayer().setMarried(1);
        partner.setPartnerId(getPlayer().getId());
        getPlayer().setPartnerId(partner.getId());
        if (partner.getGender() > 0) {
            Marriage.createMarriage(getPlayer(), partner);
        } else {
            Marriage.createMarriage(partner, getPlayer());
        }
        return true;
    }

    //结婚系统 - NPC结婚婚礼
    public boolean createEngagement(String partner_) {
        MapleCharacter partner = getCharByName(partner_);
        if (partner == null) {
            return false;
        }
        if (partner.getGender() > 0) {
            Marriage.createEngagement(getPlayer(), partner);
        } else {
            Marriage.createEngagement(partner, getPlayer());
        }
        return true;
    }

    //结婚系统 - NPC离婚
    public boolean divorceMarriage(String partner_) {
        MapleCharacter partner = getCharByName(partner_);
        if (partner == null) {
            return false;
        }
        //复原结婚对象的婚姻状态
        partner.setMarried(0);
        partner.setPartnerId(0);
        //复原自己的婚姻状态
        getPlayer().setPartnerId(0);
        getPlayer().setMarried(0);
        Marriage.divorceMarriage(partner, getPlayer());
        return true;
    }

    //hairi 装备进化 进化等级+1
    public void updateItemLevel() {
        getPlayer().updateItemLevel();
    }

    //hairi 装备进化 进化经验+1
    public void updateItemExp() {
        getPlayer().updateItemExp();
    }

    //hairi 装备进化 进化经验归零
    public void updateItemExpZero() {
        getPlayer().updateItemExpZero();
    }

    //hairi 装备进化 得到装备进化等级
    public int getItemLevel() {
        return getPlayer().getItemLevel();
    }

    //hairi 装备进化 得到装备进化经验
    public int getItemExp() {
        return getPlayer().getItemExp();
    }

    //hairi 装备进化 得到当前武器的ID
    public int getItemID() {
        return getPlayer().getItemID();
    }

    //hairi 得到武器的名称
    public String getItemName(int itemid) {
        return MapleItemInformationProvider.getInstance().getName(getPlayer().getItemID());
    }

    //hairi 得到当前装备武器的属性
    public int getWeaponInfo(int InfoNumber) {
        return getPlayer().getWeaponInfo(InfoNumber);
    }

    //hairi 升级武器
    public boolean updateWeapon(int itemid, boolean clean) {
        return getPlayer().updateWeapon(itemid, clean);
    }

    //hairi 脱掉身上武器装备
    public void unEquipWeapon() {
        getPlayer().unEquipWeapon();
    }*/
}